package com.example.parent.bookmanage_security.dao;

import com.example.parent.bookmanage_security.entity.Privilege;
import com.example.parent.bookmanage_security.entity.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户数据访问层
 * 负责与用户相关的数据库操作，如查询用户信息、查询用户权限等
 */
@Repository // 标识为数据访问层组件，由Spring容器管理
public class UserDao {

    /**
     * 注入JdbcTemplate
     * 用于执行SQL语句，实现对数据库的操作
     */
    @Autowired
    JdbcTemplate jdbcTemplate;

    /**
     * 根据用户名查询用户信息
     * 从数据库中查询指定用户名对应的用户详情
     *
     * @param username 用户名
     * @return UserDto 用户数据传输对象，包含用户基本信息
     */
    public UserDto getUserByUsername(String username) {
        // 定义查询SQL：根据用户名查询user表中的所有字段
        String sql = "select * from user where username = ?";
        // 执行查询，使用BeanPropertyRowMapper将结果集映射为UserDto对象列表
        // 第三个参数为SQL中的占位符参数（即用户名）
        List<UserDto> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(UserDto.class), username);
        // 判断查询结果：若存在且仅存在一条记录，则返回该用户对象
        if (list != null && list.size() == 1) {
            return list.get(0);
        }
        // 无匹配用户时返回null
        return null;
    }

    /**
     * 根据用户ID查询该用户拥有的权限
     * 从数据库中查询指定用户关联的所有权限信息
     *
     * @param userId 用户ID
     * @return List<String> 权限字符串列表（如"ROLE_ADMIN"、"book:read"等）
     */
    public List<String> findPrivilegesByUserId(Integer userId) {
        // 定义查询SQL：通过多表关联（user、priv、user_priv）查询用户对应的权限
        // 关联条件：用户与权限的中间表user_priv建立用户ID和权限ID的映射
        String sql = "select u.username, p.authority from user u ,priv p, user_priv up where up.user_id=u.id and up.priv_id=p.id and u.id=?";
        // 执行查询，将结果集映射为Privilege对象列表
        List<Privilege> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Privilege.class), userId);
        // 创建权限字符串列表，用于存储提取出的权限信息
        List<String> privileges = new ArrayList<>();
        // 遍历Privilege列表，提取每个权限的authority字段并添加到权限列表中
        list.forEach(p -> privileges.add(p.getAuthority()));
        // 返回权限列表
        return privileges;
    }
}